/* Thisis the control panel, This where the user can control the outcome of the graphical
 * representation using various different items e.g buttons, sliders and dropdown menus.*/

/* Author: Mark Mckillion, Chris Mowbray
 * Date: 17/04/2012
 * Version 1.0.*/
package assignment4;

import java.awt.Color;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyledDocument;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

@SuppressWarnings("serial")
public class ControlPanel extends JPanel
{   /*This class will provide the ControlPanel interface and will aloow the user
     *to specifiy the incoming and outgoing threads of cash. Will also allow the
     *user to define the duration of the program.*/
    
    //create the combo boxes that will be used to give the system input.
    protected static JComboBox<String> jComboBox1, jComboBox2, jComboBox3, jComboBox4;
    
    //Create labels to improve the layout and understandability of the program.
    private JLabel jLabel1, jLabel3, jLabel4, jLabel5, jLabel6;
    
    //Create buttons which will be used to Start/Stop/Reload the program.
    private JButton reloadButton, startButton, stopButton;
    
    //create a thread that will be used to control the GUI timings.
    public Thread thread;
    
    //create a slider that will determain the speed of the GUI.
    JSlider speedSlider;
    
    //create an int that will be taken from the slider.
    public int speedValue;
    
    //create the Strings that will appear in the combo boxes and will also control user 
    //input.
    private String [] sortingMethods = {"Bubble", "Insertion", "Selection"};
        String [] numberOfObjects = {"1", "2", "3", "4", "5", "6", "7"};
        String [] order1 = {"Light to Dark", "Dark to Light", "Order of the Rainbow",};
        String [] order2 = {"Light to Heavy", "Fast to Slow", "Expensive to Cheap"};
        String [] type = {"Colour", "Vehicle"};
        
    //create a string that will be used to determain what object type has been chosen.
    protected static String str = "Colour";
    
    // setting the textPane "algoritm" so that it is now a styled document.
    StyledDocument sdoc = ModelFrame.algoritm.getStyledDocument(); 
    // setting the attributes of the styled document so taht it can be edidited 
    // with colors and fonts.
    SimpleAttributeSet attrs = new SimpleAttributeSet();  
        
    
    {   //create the start button and add an action listener.
        startButton = new JButton();
        startButton.addActionListener(new ActionListener()
        {   @Override
            public void actionPerformed (ActionEvent ae)
            {   //create and start the thread that will update the GUI.
                thread = new  Thread (new DelayThread());
                thread.start();
                
                //disable other inputs while program is running.
                startButton.setEnabled(false);
                reloadButton.setEnabled(false);
                jComboBox1.setEnabled(false);
                jComboBox2.setEnabled(false);
                jComboBox3.setEnabled(false);
                jComboBox4.setEnabled(false);
                
                //allow the user to press the stop button.
                stopButton.setEnabled(true);
            }
        });
        
        //create the stop button and add an action listener.
        stopButton = new JButton();
        stopButton.addActionListener(new ActionListener()
        {   @SuppressWarnings("deprecation")
		@Override
            public void actionPerformed (ActionEvent ae)
            {   //reanble the input methods.
                startButton.setEnabled(true);
                reloadButton.setEnabled(true);
                jComboBox1.setEnabled(true);
                jComboBox2.setEnabled(true);
                jComboBox3.setEnabled(true);
                jComboBox4.setEnabled(true);
                
                //disable the stop button as the program has already stopped
                stopButton.setEnabled(false);
                
                //reset the values within the GUI
                DrawingPanel.sn = 0;
                DrawingPanel.comp1 = 0;
                DrawingPanel.comp2 = 0;
                ModelFrame.drawing.reDraw();
                
                //stop the thread.
                thread.stop();
            }
        });
        
        //create the reload button and add an action listener.
        reloadButton = new JButton();
        reloadButton.addActionListener(new ActionListener()
        {   @Override
            public void actionPerformed (ActionEvent ae)
            {   
                StyleConstants.setBackground(attrs, Color.WHITE);
                sdoc.setCharacterAttributes(1, 600, attrs, true);
                
                //create a new array of colours if colour is chosen.
                if("Colour".equals(ControlPanel.str))
                {   Colour.colour.createArray(jComboBox2.getSelectedIndex() + 1);
                    //repaint to show the new array
                    ModelFrame.drawing.reDraw();
                }
            
                //create a new array of vehicles if vehicle is chosen
                if("Vehicle".equals(ControlPanel.str))
                {   Vehicle.vehicle.createArray(jComboBox2.getSelectedIndex() + 1);
                    //repaint to show the new array
                    ModelFrame.drawing.reDraw();
                }
                //reset the value that controls the ticks
                DrawingPanel.sn = 0;
            }
        });
        
        //diaable the stop button until the program has been started.
        stopButton.setEnabled(false);
      
        //create the labels to improve user understanding.
        jLabel1 = new JLabel("Sorting Algorithm");
        jLabel3 = new JLabel("Speed of Display");
        jLabel4 = new JLabel("Number of Objects");
        jLabel5 = new JLabel("Object Type");
        jLabel6 = new JLabel("Sort By");
        
        //create the first combo box with an actionlistener.
        //combo box will have the strings from the sorting methods array.
        jComboBox1 = new JComboBox<String>(sortingMethods);
        jComboBox1.addActionListener(new ActionListener()
        {   @Override
            public void actionPerformed(ActionEvent e)
            {   //get current value of the combo box.
                if(e.getSource() == jComboBox1)
                {   //print the algorithm that applies to the current value.
                    if (jComboBox1.getSelectedItem().equals("Bubble")) 
                    {   //The bubble algorithm. Int's are used in the example to make it
                        //more understandable.
                        ModelFrame.algoritm.setText(" ");
                        ModelFrame.algoritm.setText(
                "public static void bubbleSort (int[] list)" + "\n" 
                + "  {"+ "\n"
                + "       int position, scan;"+ "\n"
                + "       int temp;"+ "\n"
                + "       for (position = list.length-1; position >= 0; position--)"+ "\n"
                + "        {"+ "\n"
                + "            for (scan = 0; scan <= position–1; scan++)"+ "\n"
                + "             {"+ "\n"
                + "                  if (list[scan+1] < list[scan])"+ "\n"
                + "                   {"+ "\n"
                + "                        temp = list[scan+1];"+ "\n"
                + "                        list[scan+1] = list[scan];"+ "\n"
                + "                        list[scan] = temp;"+ "\n"
                + "                   }"+ "\n"
                + "             }"+ "\n"
                + "        }"+ "\n"
                + "  }" + "\n"
                );
                    }
                    if (jComboBox1.getSelectedItem().equals("Insertion")) 
                    {   //The Insertion algorithm. Int's are used in the example to make 
                        //it more understandable.
                         ModelFrame.algoritm.setText(" ");
                         ModelFrame.algoritm.setText(
                  "public static void insertionSort( int [ ] numbers )"+ "\n"
                + "  {"+ "\n"
                + "          int temp, position;"+ "\n"
                + "          for( int index = 1; index < numbers.length; index++ )"+ "\n"
                + "           {"+ "\n"
                + "                 temp = number[index];"+ "\n"
                + "                 position = index;"+ "\n"
                + "                 while(position > 0 && numbers[position-1]>temp)"+ "\n"
                + "                               {"+ "\n"
        + "                                numbers[position] = numbers[position-1];"+ "\n"
                + "                                position--;"+ "\n"
                + "                               }"+ "\n"
                + "                 numbers[position] = temp;"+ "\n"
                + "            }"+ "\n"
                + "   }"+ "\n"
                );
                    }
                    if (jComboBox1.getSelectedItem().equals("Selection")) 
                    {   //The selection algorithm. Int's are used in the example to make 
                        //it more understandable.
                         ModelFrame.algoritm.setText(" ");
                         ModelFrame.algoritm.setText(
                  "public void selectionSort(int[] list)"+ "\n"
                + " {"+ "\n"
                + "       int minpos, temp;"+ "\n"
                + "       for (int index = 0; index < list.length - 1; index++)"+ "\n"
                + "        {"+ "\n"
                + "                   minpos = index;"+ "\n"
       + "                   for (int scan = index + 1; scan < list.length; scan++)"+ "\n"
                + "                   {"+ "\n"
                + "                          if (list[scan] < list[minpos]) "+ "\n"
                + "                          {"+ "\n"
                + "                                 minpos = scan;"+ "\n"
                + "                          }"+ "\n"
                + "                   }"+ "\n"
                + "                   temp = list[minpos];"+ "\n"
                + "                   list[minpos] = list[index];"+ "\n"
                + "                   list[index] = temp;"+ "\n"
                + "       }"+ "\n"
                + " }"+ "\n");
                    }
                }
            }
        });
        
        //create the second combo box with an actionlistener.
        //combo box will have the strings from the number of objects array.
        jComboBox2 = new JComboBox<String>(numberOfObjects);
        jComboBox2.addActionListener(new ActionListener()
        {   @Override
            public void actionPerformed(ActionEvent e)
            {   //create an array of colours if colour is chosen
                if("Colour".equals(ControlPanel.str))
                {   //define the array size using the number in the combo box.
                    Colour.colour.createArray(jComboBox2.getSelectedIndex() + 1);
                    //repaint to show the new array.
                    ModelFrame.drawing.reDraw();
                }
                
                //create an array of vehicles if vehicle is chosen
                if("Vehicle".equals(ControlPanel.str))
                {   //define the array size using the number in the combo box.
                    Vehicle.vehicle.createArray(jComboBox2.getSelectedIndex() + 1);
                    //repaint to show the new array
                    ModelFrame.drawing.reDraw();
                }
            }
        });
        
        //create the third combo box with an actionlistener.
        //combo box will have the strings from the type array.
        jComboBox3 = new JComboBox<String>(type);
        jComboBox3.addActionListener(new ActionListener()
        {   @Override
            public void actionPerformed(ActionEvent e)
            {   //get the current value of the combo box/
                if(e.getSource() == jComboBox3)
                {   //if vehicle is chosen change the available options in the sorting 
                    //methods combo box.
                    if (jComboBox3.getSelectedItem().equals("Vehicle")) 
                    {   str = "Vehicle";
                        for (int i = 0; i < order2.length; i++) 
                        {   //remove all the current strings and add the correct strings.
                            jComboBox4.removeItem(order1[i]);
                            jComboBox4.removeItem(order2[i]);
                            jComboBox4.addItem(order2[i]);
                            
                            //create a new array of vehicles.
                            Vehicle.vehicle.createArray(jComboBox2.getSelectedIndex() + 1);
                            
                            //repaint to show the new array.
                            ModelFrame.drawing.reDraw();
                        }
                    }
                    
                    //if colour is chosen change the available options in the sorting 
                    //methods combo box.
                    if (jComboBox3.getSelectedItem().equals("Colour")) 
                    {   str = "Colour";
                        for (int i = 0; i < order1.length; i++) 
                        {   //remove all the current strings and add the correct strings.
                            jComboBox4.removeItem(order2[i]);
                            jComboBox4.removeItem(order1[i]);
                            jComboBox4.addItem(order1[i]);
                            
                            //create a new array of vehicles.
                            Colour.colour.createArray(jComboBox2.getSelectedIndex() + 1);
                            
                            //repaint to show the new array.
                            ModelFrame.drawing.reDraw();
                        }
                    }
                }
            }
        });
        
        //create the forth combobox which will initialize with strings from order1
        jComboBox4 = new JComboBox<String>(order1);     
        
        //label the buttons for ease of use.
        startButton.setText("Start");
        stopButton.setText("Stop");
        reloadButton.setText("Reload");

        //create the slider and add an action listened
        speedSlider = new JSlider();
        speedSlider.addChangeListener(new ChangeListener() 
        {   @Override
            public void stateChanged(ChangeEvent e) 
            {   //get the slider value.
                speedValue = speedSlider.getValue();
                
                // methods created in all the sorting classes to get the current speed
                // of the slider to be used to update the speed to the current sorting 
                //algorithm.
                BubbleSort.getV(speedValue);
                InsertionSort.getV(speedValue);
                SelectionSort.getV(speedValue);
            }
        });
        
        //use slider features to make it more user frindly
        speedSlider.setMajorTickSpacing(1);
        speedSlider.setMaximum(10);
        speedSlider.setMinimum(1);
        speedSlider.setPaintLabels(true);
        speedSlider.setPaintTicks(true);
        speedSlider.setValue(5);

        //SwingGUI form used for layout, code from the form shown below.
        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jLabel3)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 199, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                            .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
                                .addComponent(startButton, javax.swing.GroupLayout.PREFERRED_SIZE, 86, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                                .addComponent(stopButton, javax.swing.GroupLayout.PREFERRED_SIZE, 93, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                                .addComponent(reloadButton, javax.swing.GroupLayout.DEFAULT_SIZE, 80, Short.MAX_VALUE))
                            .addComponent(speedSlider, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 279, Short.MAX_VALUE)
                            .addGroup(layout.createSequentialGroup()
                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                    .addComponent(jLabel1, javax.swing.GroupLayout.DEFAULT_SIZE, 146, Short.MAX_VALUE)
                                    .addComponent(jLabel4)
                                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
                                        .addComponent(jComboBox1, javax.swing.GroupLayout.Alignment.LEADING, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                                        .addComponent(jComboBox2, javax.swing.GroupLayout.Alignment.LEADING, 0, 128, Short.MAX_VALUE)))
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                    .addComponent(jComboBox3, javax.swing.GroupLayout.PREFERRED_SIZE, 125, javax.swing.GroupLayout.PREFERRED_SIZE)
                                    .addComponent(jLabel5, javax.swing.GroupLayout.PREFERRED_SIZE, 84, javax.swing.GroupLayout.PREFERRED_SIZE)
                                    .addComponent(jLabel6)
                                    .addComponent(jComboBox4, javax.swing.GroupLayout.PREFERRED_SIZE, 127, javax.swing.GroupLayout.PREFERRED_SIZE))))
                        .addGap(5, 5, 5)))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGap(22, 22, 22))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(135, 135, 135)
                .addContainerGap(156, Short.MAX_VALUE))
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel5)
                    .addComponent(jLabel1))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jComboBox3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jComboBox1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGap(17, 17, 17)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel4)
                    .addComponent(jLabel6))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jComboBox2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jComboBox4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 31, Short.MAX_VALUE)
                .addComponent(jLabel3)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(speedSlider, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(27, 27, 27)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(startButton)
                    .addComponent(reloadButton)
                    .addComponent(stopButton))
                .addGap(32, 32, 32))
        );
    }
    
    //create a get method which returns the slider value.
    public int getSliderValue()
    {   //gets the slider value.
        return speedValue;    
    }
}   //End of ControlPanel class.